home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / ddj0897.zip / DYN401.ZIP / class / btreenod.c < prev    next >
C/C++ Source or Header  |  1997-04-16  |  14KB  |  535 lines

  1.  
  2.  
  3. /*  Copyright (c) 1993-1996 Algorithms Corporation  */
  4. /*  All rights reserved.  */
  5.  
  6.  
  7.  
  8.  
  9. /*  This file automatically generated by dpp - do not edit  */
  10.  
  11. #define    DPP_STRATEGY    2
  12. #define    DPP_FASTWIDE    0
  13.  
  14.  
  15.  
  16. #line 18 "btreenod.d"
  17. #include <string.h> 
  18.  
  19. #define OBJECTS_PER_NODE 50 
  20.  
  21. #define MAX_DEPTH 10 
  22.  
  23.  
  24. #define MEMMOVE(a,b,c) memmove((void *)(a), (void *)(b), c) 
  25. #define MEMSET(a,b,c) memset((void *)(a), b, c) 
  26. #define MEMCPY(a,b,c) memcpy((void *)(a), (void *)(b), c) 
  27.  
  28. #define    CLASS    BTreeNode_c
  29. #define    ivType    BTreeNode_iv_t
  30.  
  31. #include "generics.h"
  32.  
  33. object    BTreeNode_c;
  34.  
  35.  
  36. #line 37 "btreenod.c"
  37. typedef struct  _BTreeNode_iv_t  {
  38.     int iUsed;
  39.     int iType;
  40.     object iKeys [ OBJECTS_PER_NODE ];
  41.     object iObjects [ OBJECTS_PER_NODE + 1 ];
  42.     object iBTree;
  43.     object iPrevious;
  44. }    BTreeNode_iv_t;
  45.  
  46.  
  47. #line 48 "btreenod.c"
  48. typedef struct  _BTreeNode_cv_t  {
  49.     object cData;
  50. }    BTreeNode_cv_t;
  51.  
  52. static    BTreeNode_cv_t    *BTreeNode_cv;
  53.  
  54.  
  55.  
  56. #line 44 "btreenod.d"
  57. cmeth objrtn BTreeNode_cm_gNewNode(object self, object btree, int type)
  58.     object obj = oSuper(BTreeNode_c, gNew, self)(self); 
  59.     accessIVsOf(obj); 
  60.     iv->iBTree = btree; 
  61.     iv->iType = type; 
  62.     if (!BTreeNode_cv->cData) 
  63.         BTreeNode_cv->cData = gNew(Constant); 
  64.     return obj; 
  65.  
  66. imeth objrtn BTreeNode_im_gDispose(object self)
  67. { BTreeNode_iv_t *iv = GetIVs(BTreeNode, self);
  68.     int i; 
  69.     object n; 
  70.  
  71.     if (iv->iType == 1) { 
  72.         for (i=0 ; i < iv->iUsed ; ++i) { 
  73.             if (n = iv->iKeys[i]) 
  74.                 gDeepDispose(n); 
  75.             if (n = iv->iObjects[i]) 
  76.                 gDispose(n); 
  77.         } 
  78.         if (n = iv->iObjects[iv->iUsed]) 
  79.             gDispose(n); 
  80.     } 
  81.     return oSuper(BTreeNode_c, gDispose, self)(self); 
  82.  
  83. imeth objrtn BTreeNode_im_gDeepDispose(object self)
  84. { BTreeNode_iv_t *iv = GetIVs(BTreeNode, self);
  85.     int i; 
  86.     object n; 
  87.  
  88.     for (i=0 ; i < iv->iUsed ; ++i) { 
  89.         if (n = iv->iKeys[i]) 
  90.             gDeepDispose(n); 
  91.         if (n = iv->iObjects[i]) 
  92.             gDeepDispose(n); 
  93.     } 
  94.     if (iv->iType == 1 && (n = iv->iObjects[iv->iUsed])) 
  95.         gDeepDispose(n); 
  96.     return oSuper(BTreeNode_c, gDispose, self)(self); 
  97.  
  98. static int bsearch2(ivType *iv, ifun cfun, object key, int *idx) 
  99.     int low = 0, high = iv->iUsed-1, mid, cond; 
  100.  
  101.     while (low <= high) { 
  102.         mid = (low + high) / 2; 
  103.         cond = cfun(key, iv->iKeys[mid]); 
  104.         if (cond < 0) 
  105.             high = mid - 1; 
  106.         else if (cond > 0) 
  107.             low = mid + 1; 
  108.         else 
  109.             break; 
  110.     } 
  111.     if (low <= high) { 
  112.         *idx = mid; 
  113.         return 1; 
  114.     } else { 
  115.         *idx = low; 
  116.         return 0; 
  117.     } 
  118.  
  119. imeth objrtn find(object self, ifun cfun, object key, object *foundKey)
  120. { BTreeNode_iv_t *iv = GetIVs(BTreeNode, self);
  121.     int found, idx; 
  122.  
  123.     found = bsearch2(iv, cfun, key, &idx); 
  124.     if (iv->iType == 2) 
  125.         if (found) { 
  126.         if (foundKey) 
  127.             *foundKey = iv->iKeys[idx]; 
  128.         return iv->iObjects[idx]; 
  129.     } else 
  130.         return NULL; 
  131.     return find(iv->iObjects[found+idx], cfun, key, foundKey); 
  132.  
  133. imeth objrtn findFirst(object self, ifun cfun, object *foundKey)
  134. { BTreeNode_iv_t *iv = GetIVs(BTreeNode, self);
  135.     if (iv->iType == 2) { 
  136.         if (foundKey) 
  137.             *foundKey = iv->iKeys[0]; 
  138.         return iv->iObjects[0]; 
  139.     } 
  140.     return findFirst(iv->iObjects[0], cfun, foundKey); 
  141.  
  142. imeth objrtn findLast(object self, ifun cfun, object *foundKey)
  143. { BTreeNode_iv_t *iv = GetIVs(BTreeNode, self);
  144.     if (iv->iType == 2) { 
  145.         if (foundKey) 
  146.             *foundKey = iv->iKeys[iv->iUsed-1]; 
  147.         return iv->iObjects[iv->iUsed-1]; 
  148.     } 
  149.     return findLast(iv->iObjects[iv->iUsed], cfun, foundKey); 
  150.  
  151. imeth objrtn findGE(object self, ifun cfun, object key, object *foundKey)
  152. { BTreeNode_iv_t *iv = GetIVs(BTreeNode, self);
  153.     int found, idx; 
  154.     object ret; 
  155.  
  156.     found = bsearch2(iv, cfun, key, &idx); 
  157.     if (iv->iType == 2) 
  158.         if (idx != iv->iUsed) { 
  159.         if (foundKey) 
  160.             *foundKey = iv->iKeys[idx]; 
  161.         return iv->iObjects[idx]; 
  162.     } else { 
  163.         if (foundKey) 
  164.             *foundKey = NULL; 
  165.         return NULL; 
  166.     } 
  167.     for (idx=idx+found ; idx <= iv->iUsed ; idx++) 
  168.         if (ret = findGE(iv->iObjects[idx], cfun, key, foundKey)) 
  169.         return ret; 
  170.     return NULL; 
  171.  
  172. imeth objrtn findGT(object self, ifun cfun, object key, object *foundKey)
  173. { BTreeNode_iv_t *iv = GetIVs(BTreeNode, self);
  174.     int found, idx; 
  175.     object ret; 
  176.  
  177.     found = bsearch2(iv, cfun, key, &idx); 
  178.     if (found) 
  179.         idx++; 
  180.     if (iv->iType == 2) 
  181.         if (idx != iv->iUsed) { 
  182.         if (foundKey) 
  183.             *foundKey = iv->iKeys[idx]; 
  184.         return iv->iObjects[idx]; 
  185.     } else { 
  186.         if (foundKey) 
  187.             *foundKey = NULL; 
  188.         return NULL; 
  189.     } 
  190.     for ( ; idx <= iv->iUsed ; idx++) 
  191.         if (ret = findGT(iv->iObjects[idx], cfun, key, foundKey)) 
  192.         return ret; 
  193.     return NULL; 
  194.  
  195. imeth objrtn findLE(object self, ifun cfun, object key, object *foundKey)
  196. { BTreeNode_iv_t *iv = GetIVs(BTreeNode, self);
  197.     int found, idx; 
  198.     object ret; 
  199.  
  200.     found = bsearch2(iv, cfun, key, &idx); 
  201.     if (iv->iType == 2) 
  202.         if (found) { 
  203.         if (foundKey) 
  204.             *foundKey = iv->iKeys[idx]; 
  205.         return iv->iObjects[idx]; 
  206.     } else if (idx) { 
  207.         if (foundKey) 
  208.             *foundKey = iv->iKeys[idx-1]; 
  209.         return iv->iObjects[idx-1]; 
  210.     } else { 
  211.         if (foundKey) 
  212.             *foundKey = NULL; 
  213.         return NULL; 
  214.     } 
  215.     for (idx=idx+found ; idx >= 0 ; idx--) 
  216.         if (ret = findLE(iv->iObjects[idx], cfun, key, foundKey)) 
  217.         return ret; 
  218.     return NULL; 
  219.  
  220. imeth objrtn findLT(object self, ifun cfun, object key, object *foundKey)
  221. { BTreeNode_iv_t *iv = GetIVs(BTreeNode, self);
  222.     int idx; 
  223.     object ret; 
  224.  
  225.     bsearch2(iv, cfun, key, &idx); 
  226.     if (iv->iType == 2) 
  227.         if (idx) { 
  228.         if (foundKey) 
  229.             *foundKey = iv->iKeys[idx-1]; 
  230.         return iv->iObjects[idx-1]; 
  231.     } else { 
  232.         if (foundKey) 
  233.             *foundKey = NULL; 
  234.         return NULL; 
  235.     } 
  236.     for ( ; idx >= 0 ; idx--) 
  237.         if (ret = findLT(iv->iObjects[idx], cfun, key, foundKey)) 
  238.         return ret; 
  239.     return NULL; 
  240.  
  241. static void collapse(ivType *liv, object lo, int deep) 
  242.     object self = liv->iPrevious; 
  243.     ivType *iv = ivPtr(self); 
  244.     int idx; 
  245.  
  246.     if (iv->iUsed == 1) 
  247.         if (iv->iPrevious) { 
  248.         collapse(iv, liv->iPrevious, deep); 
  249.         return; 
  250.     } else if (iv->iType == 1) { 
  251.         if (deep) 
  252.             gDeepDispose(lo); 
  253.         else 
  254.             gDispose(lo); 
  255.         iv->iKeys[0] = gDeepDispose(iv->iKeys[0]); 
  256.         gSetTopNode(iv->iBTree, iv->iObjects[iv->iObjects[0] == lo]); 
  257.         iv->iObjects[0] = iv->iObjects[1] = NULL; 
  258.         iv->iUsed = 0; 
  259.         gDeepDispose(self); 
  260.         return; 
  261.     } 
  262.     for (idx=0 ; iv->iObjects[idx] != lo ; idx++); 
  263.     if (!idx) { 
  264.         gDeepDispose(iv->iKeys[0]); 
  265.         MEMMOVE(iv->iKeys, iv->iKeys+1, (iv->iUsed-1)*sizeof(object)); 
  266.         MEMMOVE(iv->iObjects, iv->iObjects+1, iv->iUsed*sizeof(object)); 
  267.     } else { 
  268.         gDeepDispose(iv->iKeys[idx-1]); 
  269.         MEMMOVE(iv->iKeys+idx-1, iv->iKeys+idx, (iv->iUsed-idx)*sizeof(object)); 
  270.         MEMMOVE(iv->iObjects+idx, iv->iObjects+idx+1, (iv->iUsed-idx)*sizeof(object)); 
  271.     } 
  272.     iv->iKeys[iv->iUsed-1] = iv->iObjects[iv->iUsed] = NULL; 
  273.     iv->iUsed--; 
  274.     if (deep) 
  275.         gDeepDispose(lo); 
  276.     else 
  277.         gDispose(lo); 
  278.  
  279. imeth objrtn delete(object self, ifun cfun, object key, int deep, object prev)
  280. { BTreeNode_iv_t *iv = GetIVs(BTreeNode, self);
  281.     int found, idx; 
  282.     object res; 
  283.  
  284.     found = bsearch2(iv, cfun, key, &idx); 
  285.     if (iv->iType == 2) { 
  286.         if (!found) 
  287.             return NULL; 
  288.         if (iv->iUsed == 1 && prev) { 
  289.             iv->iPrevious = prev; 
  290.             collapse(iv, self, deep); 
  291.         } else { 
  292.             int n = iv->iUsed - idx - 1; 
  293.             if (deep) { 
  294.                 gDeepDispose(iv->iKeys[idx]); 
  295.                 gDeepDispose(iv->iObjects[idx]); 
  296.             } 
  297.             MEMMOVE(iv->iKeys+idx, iv->iKeys+idx+1, n*sizeof(object)); 
  298.             MEMMOVE(iv->iObjects+idx, iv->iObjects+idx+1, n*sizeof(object)); 
  299.             iv->iUsed--; 
  300.             iv->iKeys[iv->iUsed] = iv->iObjects[iv->iUsed] = NULL; 
  301.         } 
  302.         return self; 
  303.     } 
  304.     iv->iPrevious = prev; 
  305.     res = delete(iv->iObjects[found+idx], cfun, key, deep, self); 
  306.     iv->iPrevious = NULL; 
  307.     return res; 
  308.  
  309. static object split(object lo, ivType *left, ifun cfun) 
  310.     object to, ro, ret; 
  311.     ivType *right, *top; 
  312.     int lhalf, rhalf; 
  313.  
  314.     ro = gNewNode(CLASS, left->iBTree, left->iType); 
  315.     right = ivPtr(ro); 
  316.     if (left->iType == 2) { 
  317.         lhalf = left->iUsed / 2; 
  318.         rhalf = left->iUsed - lhalf; 
  319.         MEMCPY(right->iKeys, left->iKeys+lhalf, rhalf*sizeof(object)); 
  320.         MEMSET(left->iKeys+lhalf, 0, rhalf*sizeof(object)); 
  321.         left->iUsed = lhalf; 
  322.         right->iUsed = rhalf; 
  323.         MEMCPY(right->iObjects, left->iObjects+lhalf, rhalf*sizeof(object)); 
  324.         MEMSET(left->iObjects+lhalf, 0, rhalf*sizeof(object)); 
  325.     } else { 
  326.         lhalf = left->iUsed / 2; 
  327.         rhalf = left->iUsed - lhalf - 1; 
  328.         MEMCPY(right->iKeys, left->iKeys+lhalf+1, rhalf*sizeof(object)); 
  329.         MEMSET(left->iKeys+lhalf+1, 0, rhalf*sizeof(object)); 
  330.         left->iUsed = lhalf; 
  331.         right->iUsed = rhalf; 
  332.         MEMCPY(right->iObjects, left->iObjects+lhalf+1, (rhalf+1)*sizeof(object)); 
  333.         MEMSET(left->iObjects+lhalf+1, 0, (rhalf+1)*sizeof(object)); 
  334.     } 
  335.  
  336.     if (!(ret=to=left->iPrevious)) { 
  337.         ret = to = gNewNode(CLASS, left->iBTree, 1); 
  338.         gSetTopNode(left->iBTree, to); 
  339.         top = ivPtr(to); 
  340.         top->iKeys[0] = gDeepCopy(right->iKeys[0]); 
  341.         top->iObjects[0] = lo; 
  342.         top->iObjects[1] = ro; 
  343.         top->iUsed = 1; 
  344.     } else { 
  345.         int found, idx, n; 
  346.  
  347.         top = ivPtr(to); 
  348.         if (top->iUsed == OBJECTS_PER_NODE) { 
  349.             ret = to = split(to, top, cfun); 
  350.             top = ivPtr(to); 
  351.             found = bsearch2(top, cfun, right->iKeys[0], &idx); 
  352.             to = top->iObjects[found+idx]; 
  353.             top = ivPtr(to); 
  354.         } 
  355.         found = bsearch2(top, cfun, right->iKeys[0], &idx); 
  356.         if (found) 
  357.             gError(Dynace, "BTreeNode error"); 
  358.         n = top->iUsed - idx; 
  359.         if (n) { 
  360.             MEMMOVE(top->iKeys+idx+1, top->iKeys+idx, n*sizeof(object)); 
  361.             MEMMOVE(top->iObjects+idx+2, top->iObjects+idx+1, n*sizeof(object)); 
  362.         } 
  363.         top->iKeys[idx] = gDeepCopy(right->iKeys[0]); 
  364.         top->iObjects[idx+1] = ro; 
  365.         top->iUsed++; 
  366.     } 
  367.  
  368.     return ret; 
  369.  
  370. #line 385 "btreenod.d"
  371. #define DATA data ? data : BTreeNode_cv->cData 
  372.  
  373. imeth objrtn add(object self, ifun cfun, object key, object data, int replace, int *replaced, object prev, object *old)
  374. { BTreeNode_iv_t *iv = GetIVs(BTreeNode, self);
  375.     int found, idx; 
  376.     object tmp, ret; 
  377.  
  378.     found = bsearch2(iv, cfun, key, &idx); 
  379.     if (iv->iType == 1) { 
  380.         iv->iPrevious = prev; 
  381.         ret = add(iv->iObjects[found+idx], cfun, key, DATA, replace, replaced, self, old); 
  382.         iv->iPrevious = NULL; 
  383.         return ret; 
  384.     } 
  385.  
  386.     if (found) 
  387.         if (replace) { 
  388.         *old = iv->iObjects[idx]; 
  389.         iv->iObjects[idx] = DATA; 
  390.         *replaced = 2; 
  391.         return self; 
  392.     } else { 
  393.         *replaced = 0; 
  394.         return self; 
  395.     } 
  396.  
  397.  
  398.  
  399.     if (iv->iUsed == OBJECTS_PER_NODE) { 
  400.         iv->iPrevious = prev; 
  401.         tmp = split(self, iv, cfun); 
  402.         iv->iPrevious = NULL; 
  403.         return add(tmp, cfun, key, DATA, replace, replaced, NULL, old); 
  404.     } 
  405.  
  406.     if (idx != iv->iUsed) { 
  407.         int n = iv->iUsed - idx; 
  408.         MEMMOVE(iv->iKeys+idx+1, iv->iKeys+idx, n*sizeof(object)); 
  409.         MEMMOVE(iv->iObjects+idx+1, iv->iObjects+idx, n*sizeof(object)); 
  410.     } 
  411.     iv->iKeys[idx] = key; 
  412.     iv->iObjects[idx] = DATA; 
  413.     iv->iUsed++; 
  414.     *replaced = 1; 
  415.     return self; 
  416.  
  417. imeth objrtn BTreeNode_im_gPrint(object self, object stream)
  418. { BTreeNode_iv_t *iv = GetIVs(BTreeNode, self);
  419.     int i, n; 
  420.  
  421.     gPrintValue(self, stream); 
  422.     gPuts(stream, "\n------------------------------------------------------------\n"); 
  423.     if (iv->iType == 1) { 
  424.         n = iv->iUsed + 1; 
  425.         for (i=0 ; i < n ; i++) 
  426.             gPrint(iv->iObjects[i], stream); 
  427.     } 
  428.     return self; 
  429.  
  430. imeth objrtn BTreeNode_im_gPrintValue(object self, object stream)
  431. { BTreeNode_iv_t *iv = GetIVs(BTreeNode, self);
  432.     int i, n; 
  433.     object t; 
  434.  
  435.     vPrintf(stream, "BTree %8.8lx, %s node %8.8lx, %d used\n", iv->iBTree, iv->iType == 1 ? "Intermediate" : "Leaf", self, iv->iUsed); 
  436.     if (!iv->iBTree) 
  437.         vPrintf(stream, "ERROR: iBTRee not set\n"); 
  438.     if (iv->iPrevious) 
  439.         vPrintf(stream, "ERROR: iPrevious set\n"); 
  440.     for (i=0 ; i < iv->iUsed ; i++) { 
  441.         t = gStringRepValue(iv->iKeys[i]); 
  442.         vPrintf(stream, "%s  ", gStringValue(t)); 
  443.         gDispose(t); 
  444.     } 
  445.     for ( ; i < OBJECTS_PER_NODE ; i++) 
  446.         if (iv->iKeys[i]) 
  447.         vPrintf(stream, "\nERROR:  iKeys[%d] has an unexpected value.\n", i); 
  448.     gPuts(stream, "\n"); 
  449.     if (iv->iType == 1) { 
  450.         n = iv->iUsed + 1; 
  451.         for (i=0 ; i < n ; i++) 
  452.             vPrintf(stream, "%8.8lx  ", iv->iObjects[i]); 
  453.     } else 
  454.         for (i=0 ; i < iv->iUsed ; i++) { 
  455.         t = gStringRepValue(iv->iObjects[i]); 
  456.         vPrintf(stream, "%s  ", gStringValue(t)); 
  457.         gDispose(t); 
  458.     } 
  459.     for ( ; i <= OBJECTS_PER_NODE ; i++) 
  460.         if (iv->iObjects[i]) 
  461.         vPrintf(stream, "\nERROR:  iObjects[%d] has an unexpected value.\n", i); 
  462.     gPuts(stream, "\n"); 
  463.     return self; 
  464.  
  465.  
  466. #line 488 "btreenod.c"
  467.  
  468. objrtn    BTreeNode_initialize(void)
  469. {
  470.     static  CRITICALSECTION  cs;
  471.     static  int volatile once = 0;
  472.  
  473.     ENTERCRITICALSECTION(_CI_CS_);
  474.     if (!once) {
  475.         INITIALIZECRITICALSECTION(cs);
  476.         once = 1;
  477.     }
  478.     LEAVECRITICALSECTION(_CI_CS_);
  479.  
  480.     ENTERCRITICALSECTION(cs);
  481.  
  482.     if (BTreeNode_c) {
  483.         LEAVECRITICALSECTION(cs);
  484.         return BTreeNode_c;
  485.     }
  486.     INHIBIT_THREADER;
  487.     BTreeNode_c = gNewClass(Class, "BTreeNode", sizeof(BTreeNode_iv_t), sizeof(BTreeNode_cv_t), END);
  488.     cMethodFor(BTreeNode, gNewNode, BTreeNode_cm_gNewNode);
  489.     iMethodFor(BTreeNode, gFindBTNGE, findGE);
  490.     iMethodFor(BTreeNode, gFindBTNLT, findLT);
  491.     iMethodFor(BTreeNode, gFindBTNFirst, findFirst);
  492.     iMethodFor(BTreeNode, gFindBTNLE, findLE);
  493.     iMethodFor(BTreeNode, gPrint, BTreeNode_im_gPrint);
  494.     iMethodFor(BTreeNode, gAddBTreeNode, add);
  495.     iMethodFor(BTreeNode, gFindBTNEQ, find);
  496.     iMethodFor(BTreeNode, gFindBTNLast, findLast);
  497.     iMethodFor(BTreeNode, gDispose, BTreeNode_im_gDispose);
  498.     iMethodFor(BTreeNode, gFindBTNGT, findGT);
  499.     iMethodFor(BTreeNode, gDeleteBTNode, delete);
  500.     iMethodFor(BTreeNode, gDeepDispose, BTreeNode_im_gDeepDispose);
  501.     iMethodFor(BTreeNode, gPrintValue, BTreeNode_im_gPrintValue);
  502.  
  503.     BTreeNode_cv = GetCVs(BTreeNode);
  504.  
  505.     ENABLE_THREADER;
  506.  
  507.     LEAVECRITICALSECTION(cs);
  508.  
  509.     return BTreeNode_c;
  510. }
  511.  
  512.  
  513.  
  514.